#pragma once

#include"Protocol.hpp"
#include"Logger.hpp"
#include<iostream>
#include<functional>

using handler_t = std::function<Responce(Request& req)>;

class Parser
{
public:
    Parser(handler_t handler):_handler(handler)
    {}
    ~Parser(){}
    //对报文进行解析：获取完整报文 -> 解包-> 反序列化 -> 获取数据 -> 处理任务获得结果 -> 将结果序列化 ->打包 ->发送
    std::string Parse(std::string& inbuffer)//输入、输出型参数
    {
        LOG(LogLevel::DEBUG) << "inbuffer: \r\n" << inbuffer;

        std::string send_str;
        while(true)//inbuffer 中可能存在多个完整的报文，故而使用while
        {
            std::string jsonstr;
            //1、解包
            int n = Protocol::Unpack(inbuffer , &jsonstr);//返回获取到的报文长度,为0表示inbuffer 中没有完整报文，为-1表示报文协议错误
            LOG(LogLevel::DEBUG) << "解包结果: " << n;

            if(n==0) break;//退出去，上一层函数会继续进行读取数据
            // else if(n<0) exit(0);
            else if(n<0) break;//此处是单进程，就不要使用exit(0)
            else
            {
                LOG(LogLevel::DEBUG) << "解包成功:\r\n " << jsonstr;
                //获取到了完整的报文，存放在 jsonstr 中
                //2、反序列化；创建Request 对象，其中有反序列化的方法,成功返回true ，失败返回false
                Request req;
                if(!req.Deserialize(jsonstr))
                {
                    //反序列失败
                    return std::string();
                }

                //3、进行任务处理并获取结果
                Responce resp = _handler(req);
                LOG(LogLevel::DEBUG) <<  "解包、反序列结果：";
                resp.Print();


                //4、将结果进行序列化，成功返回true,失败返回false
                //Responce 中的序列化方法,输出型参数
                std::string resp_json;
                if(!resp.Serialize(&resp_json))
                {
                    return std::string();
                }
                
                //5、将结果进行打包, Package 会返回成功打包的字符串
                send_str += Protocol::Package(resp_json);
            }
        }
        return send_str;
    }
private:
    handler_t _handler;//处理数据的方法放在类Calculator 中
};